package at.jku.ase.utils;

import sun.misc.BASE64Decoder;

import java.io.*;

public final class ObjectUtils {

    private ObjectUtils() {
    }

    private final static BASE64Decoder base64Decoder = new BASE64Decoder();

    public static <T> T convert(final byte[] byteArray) {
        return new OpWithParameterThrowsException<T>() {
            @Override
            public T op() throws Exception {
                ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
                ObjectInputStream ois = new ObjectInputStream(bis);
                T obj = (T) ois.readObject();
                ois.close();
                bis.close();
                return obj;
            }
        }.execute();
    }

    public static <T> T convert(final String encodedText) {
        return new OpWithParameterThrowsException<T>() {
            @Override
            public T op() throws Exception {
                byte[] bytes = base64Decoder.decodeBuffer(encodedText);
                ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
                ObjectInputStream ois = new ObjectInputStream(bis);
                T obj = (T) ois.readObject();
                ois.close();
                bis.close();
                return obj;
            }
        }.execute();
    }

    public static <T> T convert(final char[] charArray) {
        return new OpWithParameterThrowsException<T>() {
            @Override
            public T op() throws Exception {
                StringBuilder builder = new StringBuilder();
                builder.append(charArray);
                byte[] rawKey = base64Decoder.decodeBuffer(builder.toString());
                return convert(rawKey);
            }
        }.execute();
    }

    public static byte[] convert(final Object obj) {
        return new OpWithParameterThrowsException<byte[]>() {
            @Override
            public byte[] op() throws Exception {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutput out = new ObjectOutputStream(bos);
                out.writeObject(obj);
                byte[] result = bos.toByteArray();
                out.close();
                bos.close();
                return result;
            }
        }.execute();
    }

    public static byte[] toByteArray(char[] chars) {
        return toByteArray(new String(chars));
    }

    public static byte[] toByteArray(String base64) {
        try {
            return base64Decoder.decodeBuffer(base64);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
